package ru.spb.osll.myfit.client.widget;

import java.util.ArrayList;

import ru.spb.osll.myfit.client.PageMode;
import ru.spb.osll.myfit.client.event.PageEvent;
import ru.spb.osll.myfit.client.event.PageEvent.PageEventType;
import ru.spb.osll.myfit.common.PageElement;
import ru.spb.osll.myfit.common.PageElementType;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.PopupPanel;

public abstract class PageElementWidget extends Composite {

  protected PageMode m_mode;
  protected GWTWidgetFactory m_gwtWidgetFactory;
  protected PopupPanel m_rootPopupMenu;
  protected MenuBar m_rootMenuBar;
  private ArrayList<PageEventListener> listeners = new ArrayList<PageEventListener>();

  public PageElementWidget(GWTWidgetFactory gwtWidgetFactory) {
    m_gwtWidgetFactory = gwtWidgetFactory;
    m_rootPopupMenu = m_gwtWidgetFactory.createPopupPanel();
    m_rootMenuBar = m_gwtWidgetFactory.createMenuBar();
    m_mode = PageMode.VIEW;
  }

  abstract public PageElement save();

  abstract public void setOpen(boolean isOpen);

  protected void createPopupMenu() {

    MenuItem deletePageElement = m_gwtWidgetFactory.createMenuItem("Delete",
        false, new Command() {

          @Override
          public void execute() {
            m_rootPopupMenu.hide();
            for (PageEventListener listener : listeners) {
              listener.actionPerformed(new PageEvent(
                  PageEventType.DELETE_PAGE_ELEMENT, false,
                  PageElementWidget.this));
            }
          }
        });

    MenuBar addElementBefore = m_gwtWidgetFactory.createMenuBar();
    MenuItem addIncludeBefore = m_gwtWidgetFactory.createMenuItem("Incude",
        false, new Command() {

          @Override
          public void execute() {
            m_rootPopupMenu.hide();
            for (PageEventListener listener : listeners) {
              listener.actionPerformed(new PageEvent(PageEventType.ADD_INCLUDE,
                  true, PageElementWidget.this));
            }
          }
        });

    MenuItem addTableBefore = m_gwtWidgetFactory.createMenuItem("Table", false,
        new Command() {

          @Override
          public void execute() {
            m_rootPopupMenu.hide();
            for (PageEventListener listener : listeners) {
              listener.actionPerformed(new PageEvent(PageEventType.ADD_TABLE,
                  true, PageElementWidget.this));
            }
          }
        });

    MenuItem addWikiBefore = m_gwtWidgetFactory.createMenuItem("Wiki", false,
        new Command() {

          @Override
          public void execute() {
            m_rootPopupMenu.hide();
            for (PageEventListener listener : listeners) {
              listener.actionPerformed(new PageEvent(PageEventType.ADD_WIKI,
                  true, PageElementWidget.this));
            }
          }
        });

    addElementBefore.addItem(addIncludeBefore);
    addElementBefore.addItem(addTableBefore);
    addElementBefore.addItem(addWikiBefore);

    MenuBar addElementAfter = m_gwtWidgetFactory.createMenuBar();
    MenuItem addIncludeAfter = m_gwtWidgetFactory.createMenuItem("Incude",
        false, new Command() {

          @Override
          public void execute() {
            m_rootPopupMenu.hide();
            for (PageEventListener listener : listeners) {
              listener.actionPerformed(new PageEvent(PageEventType.ADD_INCLUDE,
                  false, PageElementWidget.this));
            }
          }
        });

    MenuItem addTableAfter = m_gwtWidgetFactory.createMenuItem("Table", false,
        new Command() {

          @Override
          public void execute() {
            m_rootPopupMenu.hide();
            for (PageEventListener listener : listeners) {
              listener.actionPerformed(new PageEvent(PageEventType.ADD_TABLE,
                  false, PageElementWidget.this));
            }
          }
        });

    MenuItem addWikiAfter = m_gwtWidgetFactory.createMenuItem("Wiki", false,
        new Command() {

          @Override
          public void execute() {
            m_rootPopupMenu.hide();
            for (PageEventListener listener : listeners) {
              listener.actionPerformed(new PageEvent(PageEventType.ADD_WIKI,
                  false, PageElementWidget.this));
            }
          }
        });

    addElementAfter.addItem(addIncludeAfter);
    addElementAfter.addItem(addTableAfter);
    addElementAfter.addItem(addWikiAfter);

    m_rootMenuBar.addItem(deletePageElement);
    m_rootMenuBar.addItem("Add before...", addElementBefore);
    m_rootMenuBar.addItem("Add after...", addElementAfter);

    m_rootPopupMenu.setWidget(m_rootMenuBar);
  }

  public void setPageEventListener(PageEventListener pageEventListener) {
    listeners.add(pageEventListener);
  }

  public void removePageEventListener(PageEventListener pageEventListener) {
    listeners.remove(pageEventListener);
  }

  public abstract PageElementType getType();

  protected void onRightClick(Event event) {
    if (m_mode.equals(PageMode.VIEW)) {
      return;
    }
    int x = event.getClientX();
    int y = event.getClientY() + Window.getScrollTop();
    event.stopPropagation();
    m_rootPopupMenu.setPopupPosition(x, y);
    m_rootPopupMenu.show();
  }

  public void onBrowserEvent(Event event) {
    GWT.log("onBrowserEvent", null);
    event.preventDefault();
    switch (DOM.eventGetType(event)) {
    case Event.ONMOUSEUP:
      if (DOM.eventGetButton(event) == Event.BUTTON_LEFT) {
        GWT.log("Event.BUTTON_LEFT", null);
      }

      if (DOM.eventGetButton(event) == Event.BUTTON_RIGHT) {
        GWT.log("Event.BUTTON_RIGHT", null);
        onRightClick(event);
      }

      break;

    case Event.ONDBLCLICK:
      break;

    case Event.ONCONTEXTMENU:
      GWT.log("Event.ONCONTEXTMENU", null);
      break;

    default:
      break;
    }
  }

  public void setMode(PageMode mode) {
    m_mode = mode;
  }
}
